package org.xq.softcup.mq.remoting.provider.impl;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.xq.softcup.mq.registry.ServiceRegistry;
import org.xq.softcup.mq.remoting.net.NetEnum;
import org.xq.softcup.mq.remoting.provider.XQRpcProviderFactory;
import org.xq.softcup.mq.remoting.provider.annotation.XQRpcService;
import org.xq.softcup.mq.serialize.Serializer;
import org.xq.softcup.mq.util.XQRpcException;

import java.util.Map;

public class XQRpcSpringProviderFactory extends XQRpcProviderFactory implements ApplicationContextAware, InitializingBean, DisposableBean {
    private String netType = NetEnum.NETTY.name();
    private String serialize = Serializer.SerializeEnum.HESSIAN.name();
    private String ip;
    private int port;
    private String accessToken;
    private Class<? extends ServiceRegistry> serviceRegistryClass;
    private Map<String, String> serviceRegistryParam;

    public void setNetType(String netType) {
        this.netType = netType;
    }

    public void setSerialize(String serialize) {
        this.serialize = serialize;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }

    public void setServiceRegistryClass(Class<? extends ServiceRegistry> serviceRegistryClass) {
        this.serviceRegistryClass = serviceRegistryClass;
    }

    public void setServiceRegistryParam(Map<String, String> serviceRegistryParam) {
        this.serviceRegistryParam = serviceRegistryParam;
    }

    private void prepareConfig() {
        NetEnum netTypeEnum = NetEnum.autoMatch(this.netType, null);
        Serializer.SerializeEnum serializeEnum = Serializer.SerializeEnum.match(this.serialize, null);
        Serializer serializer = serializeEnum != null ? serializeEnum.getSerializer() : null;

        System.out.println("服务端初始化配置");
        super.initConfig(netTypeEnum, serializer, this.ip, this.port, this.accessToken, this.serviceRegistryClass, this.serviceRegistryParam);
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String, Object> serviceBeanMap = applicationContext.getBeansWithAnnotation(XQRpcService.class);
        if ((serviceBeanMap != null) && (serviceBeanMap.size() > 0)) {
            for (Object serviceBean : serviceBeanMap.values()) {
                if (serviceBean.getClass().getInterfaces().length == 0) {
                    throw new XQRpcException("调用服务必须实现接口.");
                }
                XQRpcService xqRpcService = (XQRpcService) serviceBean.getClass().getAnnotation(XQRpcService.class);

                String iface = serviceBean.getClass().getInterfaces()[0].getName();
                String version = xqRpcService.version();

                super.addService(iface, version, serviceBean);
            }
        }
    }

    public void afterPropertiesSet() throws Exception {
        prepareConfig();
        super.start();
    }

    public void destroy() throws Exception {
        super.stop();
    }
}
